﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
#include <algorithm>
using namespace std;

//class Solution 
//{
//public:
//	// 这⾥的传值返回拷⻉代价就太⼤了
//	vector<vector<int>> generate(int numRows) 
//	{
//		vector<vector<int>> vv(numRows);
//		for (int i = 0; i < numRows; ++i)
//		{
//			vv[i].resize(i + 1, 1);
//		}
//		for (int i = 2; i < numRows; ++i)
//		{
//			for (int j = 1; j < i; ++j)
//			{
//				vv[i][j] = vv[i - 1][j] + vv[i - 1][j - 1];
//			}
//		}
//		return vv;
//	}
//};

namespace wxw
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		string(const string& s)
			:_str(nullptr)
			, _size(0), _capacity(0)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}
		 //移动构造
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;//直接转移资源
			swap(s);
		}
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}
		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}
		/*~string()
		{
			cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}*/
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}
				_str = tmp;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity *
					2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		const char* c_str() const
		{
			return _str;
		}
		size_t size() const
		{
			return _size;
		}
private:
	char* _str = nullptr;
	size_t _size = 0;
	size_t _capacity = 0;
	};
}

//class Solution
//{
//public:
//	// 传值返回需要拷⻉
//	wxw::string addStrings(wxw::string num1, wxw::string num2)
//	{
//		wxw::string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		return str;
//	}
//};
//int main()
//{
//	wxw::string ret;
//	ret = Solution().addStrings("11111", "222222");
//	return 0;
//}

//class Solution
//{
//public:
//	// 传值返回需要拷⻉
//	wxw::string addStrings(wxw::string num1, wxw::string num2)
//	{
//		wxw::string str;
//		int end1 = num1.size() - 1, end2 = num2.size() - 1;
//		// 进位
//		int next = 0;
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			int ret = val1 + val2 + next;
//			next = ret / 10;
//			ret = ret % 10;
//			str += ('0' + ret);
//		}
//		if (next == 1)
//			str += '1';
//		reverse(str.begin(), str.end());
//		return str;
//	}
//};
//int main()
//{
//	wxw::string ret = Solution().addStrings("11111", "222222");
//	return 0;
//}

//typedef int& lref;
//typedef int&& rref;
//
//int main()
//{
//	int n = 0;
//	
//	lref& r1 = n;//r1的类型是int&
//	lref&& r2 = n;//r2的类型是int&
//	rref& r3 = n;// r3的类型是int&
//	rref&& r4 = 1;//r4的类型是int&&
//
//	f1<int>(n);//没有折叠->实例化为void f1(int& x)
//	//f1<int>(0); //报错
//
//	f1<int&>(n);//折叠->实例化为void f1(int& x)
//	//f1<int&>(1);//报错不能传右值
//
//	f1<int&&>(n);//折叠->实例化为void f1(int& x)
//	//f1<int&&>(1);//报错
//
//	f1<const int&>(n);//折叠->实例化为void f1(const int& x)
//	f1<const int&>(0);
//
//	f1<const int&&>(n);//折叠->实例化为void f1(const int& x)
//	f1<const int&&>(0);
//
//	//f2<int>(n); 报错
//	f2<int>(1);//没有折叠->实例化为void f2(int&&)
//
//	f2<int&>(n);//引用折叠->实例化为void f2(int&)
//	//f2<int&>(0);//报错
//
//	//f2<int&&>(n);//报错
//	f2<int&&>(0);//引用折叠->实例化为void f2(int&&)
//
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	x++;
//	cout << &a << endl;
//	cout << &x << endl;
//}
//
//int main()
//{
//	Function(10);//10是右值，T推导出来是int，模版实例化为void Function(int&& t)
//				 //此时函数中T x = a;为int x = a。两个不同的变量地址不同
//
//	int a;//左值
//	Function(a);//a是左值，T推导出来是int&,引用折叠，模版实例化为void Function(int& t)
//				//此时T x = a;为int& x = a。两个相同的地址。
//
//	Function(move(a));//move(a)是右值，T推导出来时int，模版参数实例化为void Function(int&& t)
//					  //此时T x = a 为int x = a
//
//	const int b = 8;
//	Function(b);//b是左值，T推导出来是const int&,引用折叠，模版实例化为void Function(const int& t)
//				//此时T x = a 为const int& x = a所以Function内部会编译报错,x不能++。
//
//	Function(move(b));//move(b)是右值，T推导出来是const int,模版实例化为void Function(const int&& t)
//						//此时T x = a为const int x = a。
//	return 0;
//}

//void Fun(int& x)
//{
//	cout << "左值引用" << endl;
//}
//void Fun(const int& x)
//{
//	cout << "const 左值引用" << endl;
//}
//void Fun(int&& x)
//{
//	cout << "右值引用" << endl;
//}
//void Fun(const int&& x)
//{
//	cout << "const 右值引用" << endl;
//}
//
//template<class T>
//void Function(T&& t)
//{
//	//Fun(t);
//	Fun(forward<T>(t));
//}
//
//int main()
//{
//	Function(10);//10是右值，推导出T为int，模版实例化为void Function(int&& t)
//				 
//	int a;//左值
//	Function(a);//a是左值，T推导出来是int&,引用折叠，模版实例化为void Function(int& t)
//
//	Function(move(a));//move(a)是右值，T推导出来时int，模版参数实例化为void Function(int&& t)
//
//	const int b = 8;
//	Function(b);//b是左值，T推导出来是const int&,引用折叠，模版实例化为void Function(const int& t)
//
//	Function(move(b));//move(b)是const右值，T推导出来是const int,模版实例化为void Function(const int&& t)
//	return 0;
//}

//#include"List.h"
//
//int main()
//{
//	wxw::list<wxw::string> lt;
//	wxw::string s1 = "1111111";
//	lt.push_back(s1);
//
//	wxw::string s2("22222222");
//	lt.push_back(move(s2));
//
//	lt.push_back("3333333333");
//
//	return 0;
//}

//template<class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	double x = 5.2;
//	Print();//包里有零个参数
//	Print(1);//包里有一个参数
//	Print(1, string("123456"));//包里有两个参数
//	Print(1, string("aaaaaa"), x);//包里有三个参数
//
//	return 0;
//}

//void ShowList()
//{
//	cout << endl;
//}
//
//template<class T, class ...Args>
//void ShowList(T x, Args... args)
//{
//	cout << x << " ";
//	ShowList(args...);
//}
//
//template<class ...Args>
//void Print(Args... args)
//{
//	//args是N个参数的参数包
//	//调用ShowList，参数包的第一个参数传给了x
//	//剩下的N-1个参数传给第二个参数包
//	ShowList(args...);
//}
//
//int main()
//{
//	Print(1, string("111111"), 2.2);
//	return 0;
//}

//#include <list>
//int main()
//{
//	list<wxw::string> lt;
//
//	wxw::string s1("111111");
//	lt.emplace_back(s1);//传左值，跟push_back一样，走拷贝构造
//	cout << "**********************" << endl;
//
//	lt.emplace_back(move(s1));//右值，跟push_back一样，走移动构造
//	cout << "**********************" << endl;
//	
//	lt.emplace_back("11111111");//直接构造，用string参数包构造string，push_back做不到
//	cout << "**********************" << endl;
//
//
//	list<pair<wxw::string, int>> lt2;
//	//跟push_back一样，构造pair + 拷贝构造pair到list节点的data上
//	pair<wxw::string, int> kv("苹果", 1);
//	lt2.emplace_back(kv);
//	cout << "**********************" << endl;
//
//	lt2.emplace_back(move(kv));
//	//跟push_back一样，构造pair + 移动构造pair到list节点的data上
//	cout << "**********************" << endl;
//
//	//直接构造pair参数包往下传，直接用pair参数包构造pair
//	lt2.emplace_front("苹果", 1);
//	cout << "**********************" << endl;
//
//	return 0;
//}
//#include <list>
//#include"List.h"
//int main()
//{
//	wxw::list<wxw::string> lt;
//
//	wxw::string s1("111111");
//	lt.emplace_back(s1);//传左值，跟push_back一样，走拷贝构造
//	cout << "**********************" << endl;
//
//	lt.emplace_back(move(s1));//右值，跟push_back一样，走移动构造
//	cout << "**********************" << endl;
//	
//	lt.emplace_back("11111111");//直接构造，用string参数包构造string，push_back做不到
//	cout << "**********************" << endl;
//
//
//	list<pair<wxw::string, int>> lt2;
//	//跟push_back一样，构造pair + 拷贝构造pair到list节点的data上
//	pair<wxw::string, int> kv("苹果", 1);
//	lt2.emplace_back(kv);
//	cout << "**********************" << endl;
//
//	lt2.emplace_back(move(kv));
//	//跟push_back一样，构造pair + 移动构造pair到list节点的data上
//	cout << "**********************" << endl;
//
//	//直接构造pair参数包往下传，直接用pair参数包构造pair
//	lt2.emplace_front("苹果", 1);
//	cout << "**********************" << endl;
//
//	return 0;
//}

//int main()
//{
//	auto add1 = [](int x, int y) ->int {return x + y; };
//	cout << add1(1, 2) << endl;
//
//	//1、捕捉列表为空也不能省略
//	//2、参数为空可以省略
//	//3、返回值可以省略
//	//4、函数体不能省略
//	auto func1 = []
//	{
//		cout << "hello world" << endl;
//		return 0;
//	};
//
//	func1();
//
//	return 0;
//}


//int main()
//{
//	int a = 0, b = 1, c = 2, d = 3;
	//auto func1 = [a, &b]
	//{
	//	//值捕捉的变量不能修改，引用捕捉的变量可以修改
	//	//a++;
	//	b++;
	//	int ret = a + b;
	//	return ret;
	//};
	//cout << func1() << endl;

	////用那些变量就捕捉那些变量
	////隐式值捕捉
	//auto func2 = [=]
	//{
	//	int ret = a + b + c;
	//	return ret;
	//};
	//cout << func2() << endl;

	////隐式引用捕捉
	//auto func3 = [&]
	//{
	//	a++;
	//	b++;
	//	c++;
	//};
	//func3();
	//cout << a << " " << b << " " << c << " " << d << endl;

	//混合捕捉
//	auto func4 = [&, a, b]
//	{
//		c++;
//		d++;
//		return a + b + c + d;
//	};
//	func4();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	cout << func4() << endl;
//
//	//混合捕捉
//	auto func5 = [=, &a, &b]
//	{
//		a++;
//		b++;
//		return a + b + c + d;
//	};
//	func5();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	cout << func5() << endl;
//	return 0;
//}

//int x = 0;
//
//int main()
//{
//	static int m = 0;
//	//局部的静态变量不能捕捉，也不需要捕捉
//	auto func6 = []
//	{
//		int ret = m + x;
//		return ret;
//	};
//
//	int a = 0, b = 1, c = 2, d = 3;
//	//传值捕捉本质是一种拷贝，并且被const修饰了
//	//mutable相当于去掉了const属性，可以修改了
//	//但是修改了不会影响外面被捕捉的值，因为是一种拷贝
//	auto func7 = [=]() mutable
//	{
//		a++;
//		b++;
//		c++;
//		d++;
//
//		return a + b + c + d;
//	};
//	func7();
//	cout << a << " " << b << " " << c << " " << d << endl;
//	cout << func7() << endl;
//	return 0;
//}

//struct Goods
//{
//	string _name;//姓名
//	double _price;//价格
//	int _number;//数量
//
//	Goods(const char* str, double price, int number)
//		:_name(str)
//		,_price(price)
//		,_number(number)
//	{}
//};
//
//struct ComparePriceLess
//{
//	bool operator()(const Goods& g1, const Goods& g2)
//	{
//		return g1._price < g2._price;
//	}
//};
//
//struct ComparePriceGreater
//{
//	bool operator()(const Goods& g1, const Goods& g2)
//	{
//		return g1._price > g2._price;
//	}
//};
//
//int main()
//{
//	vector<Goods> v = { {"苹果", 5.0, 10}, {"香蕉", 3.5, 6}, {"橙子", 2.2, 3}, {"菠萝", 3, 10} };
//
//	//类似这样的场景，我们实现仿函数对象或者函数指针支持商品中不同项的比较，
//	//相对还是比较麻烦的，这里使用lambda来简化程序
//	sort(v.begin(), v.end(), ComparePriceLess());
//	sort(v.begin(), v.end(), ComparePriceGreater());
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price < g2._price;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._price > g2._price; 
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._number < g2._number;
//		});
//
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2) {
//		return g1._number > g2._number;
//		});
//
//	return 0;
//}
//
//class Rate
//{
//public:
//	Rate(double rate)
//		: _rate(rate)
//	{}
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//private:
//	double _rate;
//};
//
//int main()
//{
//	double rate = 0.49;
//	// lambda
//	auto r2 = [rate](double money, int year) {
//		return money * rate * year;
//	};
//	// 函数对象
//	Rate r1(rate);
//	r1(10000, 2);
//	r2(10000, 2);
//	auto func1 = [] {
//		cout << "hello world" << endl;
//	};
//	func1();
//	return 0;
//}

//class Person
//{
//public:
//	Person(const char* name = "张三", int age = 0)
//		:_name(name)
//		,_age(age)
//	{}
//
//	Person(const Person& p)
//		:_name(p._name)
//		,_age(p._age)
//	{}
//
//	Person(Person&& p) = default;
//private:
//	wxw::string _name;
//	int _age;
//};
//
//int main()
//{
//	Person s1;
//	//Person s2 = s1;//显式声明了移动构造，编译器隐式删除了默认的拷贝赋值运算符
//	Person s3 = move(s1);
//	Person s4;
//	//s4 = move(s2);
//	return 0;
//}


//#include<functional>
//
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator()(int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{}
//
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//
//private:
//	int _n;
//};
//
//int main()
//{
//	//包装各种可调用对象
//	function<int(int, int)> f1 = f;
//	function<int(int, int)> f2 = Functor();
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; };
//
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	//包装静态成员函数
//	//成员函数要指定类域并且前面加&才能获取到地址
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl;
//
//	//包装普通成员函数
//	//普通成员函数还有一个隐含的this指针参数，所以绑定时传函数对象或者函数的指针过去。
//	function<double(Plus*, double, double)> f5 = &Plus::plusd;
//	Plus pd;
//	cout << f5(&pd, 1.1, 2.2) << endl;
//
//	function<double(Plus, double, double)> f6 = &Plus::plusd;
//	cout << f6(pd, 1.1, 2.2) << endl;
//
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(move(pd), 1.1, 2.2) << endl;
//	cout << f7(Plus(), 1.1, 2.2) << endl;
//
//	return 0;
//}

#include<functional>

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return a - b;
}


class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	//bind 本质返回的一个仿函数对象

	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;

	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;

	//调整参数个数
	auto sub3 = bind(Sub, 100, _1);
	cout << sub3(5) << endl;

	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(5) << endl;

	//bind用于绑死一些固定参数
	function<double(double, double)> ff = bind(&Plus::plusd, Plus(), _1, _2);
	cout << ff(1.1, 2.2) << endl;
	return 0;
}

